iT邦幫忙

第 12 屆 iThome 鐵人賽

DAY 26
0
Modern Web

我不用Expo啦,React Native!系列 第 26

[Day26] 設定頁面-1:頁面改造

  • 分享至 

  • xImage
  •  

由於之前只有隨便寫一點按鈕
今天來把介面改造一下

開始改造前要先來張留念照
https://ithelp.ithome.com.tw/upload/images/20200924/20121828uiGozpcIFh.png

這時候來google一下頁面來點靈感
https://ithelp.ithome.com.tw/upload/images/20200924/20121828NtchVq7xNq.png


看一看打算做一個列表式的感覺
一欄是一個按鈕
切換語言的按鈕除了切換語言外,還會顯示目前的語言
點進去後會切換到語言選擇的頁面


既然要做有頁面點進點出的動作,當然又要用到StackNavigator
不過由於設定頁面的結構不同於其他三頁
所以不能重複使用Day14寫的AnimeStack.tsx
要另外寫個Stack
包含外部的SettingContent及內部的LanguageChanging

const SettingScreen = () => {
  const { t } = useTranslation()

  return (
    <Stack.Navigator>
      <Stack.Screen
        name="Setting"
        options={() => ({
          title: t('Setting.title')
        })}
        component={SettingContent}
      />
      <Stack.Screen
        name="LanguageChanging"
        options={() => ({
          title: t('Setting.changeLanguage')
        })}
        component={LanguageChanging}
      />
    </Stack.Navigator>
  )
}

SettingContent

const SettingContent = () => {
  const dispatch = useDispatch()
  // 從store抓取當前語言
  const language = useSelector((state: RootStateType) => state.language)
  
  ...
  
      <TouchableOpacity
        activeOpacity={1}
        style={styles.language}
        onPress={() => {
          navigation.navigate('LanguageChanging')
        }}>
        <!--點下按鈕後導航到語言切換-->
        <View style={{ flexDirection: 'row' }}>
          <Ionicons name="language" color="green" size={24} />
          <View style={styles.textAtMiddle}>
            <Text style={{ fontSize: 24 }}>{t('Setting.language')}</Text>
          </View>
        </View>
        <View style={{ flexDirection: 'row' }}>
          <View style={styles.textAtMiddle}>
            <!--顯示當前語言-->
            <Text style={styles.languageNow}>{t(`Setting.${language}`)}</Text>
          </View>
          <Ionicons name="chevron-forward" color="#C8C8C8" size={24} />
        </View>
      </TouchableOpacity>

由於有使用i18n,使用的地方都要記得打翻譯檔(寫幾種語言就要打幾份...)

const tw: AnimePageData = {
  ...
  [routes[3].name]: {
    title: '設定',
    language: '語言',
    'zh-TW': '繁體中文',
    ja: '日文',
    en: '英文',
    changeLanguage: '切換語言'
  }
}

呈現出列表的感覺
https://ithelp.ithome.com.tw/upload/images/20200924/20121828bBTzlAU882.png

LanguageChanging

這裡單純列出中英日三種語言
並且比對store的狀態處於哪一種語言
並在該種語言旁邊打勾

const LanguageChanging = () => {
  const dispatch = useDispatch()
  const language = useSelector((state: RootStateType) => state.language)
  const { t } = useTranslation()
  const langArray = ['zh-TW', 'ja', 'en']

  const changeLang = (lang: string) => {
    dispatch(renewLanguage(lang))
  }

  ...
        {langArray.map((lang) => (
          <TouchableOpacity
            activeOpacity={1}
            style={styles.language}
            onPress={() => {
              changeLang(lang)
            }}
            key={lang}>
            <View style={{ flexDirection: 'row' }}>
              <View style={{ ...styles.textAtMiddle, marginLeft: 10 }}>
                <Text style={{ fontSize: 24 }}>{t(`Setting.${lang}`)}</Text>
              </View>
            </View>
            <View style={{ flexDirection: 'row' }}>
              <View style={styles.textAtMiddle}>
                {lang === language && (
                  <Ionicons name="checkmark-sharp" color="green" size={24} />
                )}
              </View>
            </View>
          </TouchableOpacity>
        ))}
...

SettingContent的排版其實基本一樣
https://ithelp.ithome.com.tw/upload/images/20200924/20121828A2SVxHbduT.png


接著也改造reset按鈕

      <TouchableOpacity style={styles.resetData} onPress={() => dispatch(resetData())}>
        <Text style={styles.resetDataText}>{t('Setting.resetData')}</Text>
      </TouchableOpacity>

外觀
https://ithelp.ithome.com.tw/upload/images/20200924/20121828vo4SnTyPFo.png

同時在reducer中新增清空的操作

    case animeActions.RESET_DATA:
      for (let i = 0; i < allAnimeCopy.length; i += 1) {
        if (allAnimeCopy[i].isReminding) {
          NotifService.cancelNotif(allAnimeCopy[i])
          allAnimeCopy[i].isReminding = false
        }

        allAnimeCopy[i].isReminding = false
      }
      storeFavorite([])
      return allAnimeCopy

跑了一下發現點下去資料沒被清空/images/emoticon/emoticon19.gif
...
...
...

    case animeActions.RESET_DATA:
      for (let i = 0; i < allAnimeCopy.length; i += 1) {
        if (allAnimeCopy[i].isReminding) {
          NotifService.cancelNotif(allAnimeCopy[i])
          allAnimeCopy[i].isReminding = false
        }
        // 剛剛打錯了Orz
        allAnimeCopy[i].isFavorite = false
      }
      storeFavorite([])
      return allAnimeCopy

只能說眼殘很可怕/images/emoticon/emoticon06.gif


明天再來繼續把設定頁面完成


上一篇
[Day25] 語言切換-2:store架構調整
下一篇
[Day27] 設定頁面-2
系列文
我不用Expo啦,React Native!33
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言